﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HQDBF;
using CLFramework.Utility;
using System.Windows.Forms;

namespace StockMonitor.Business
{
    /// <summary>
    /// ETF价格提供程序，基于每分钟保存一次的实时价格sqlite库，有缓存优化策略
    /// </summary>
    /// <remarks>
    /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
    /// 编写时间：<datetime>2012-10-25 5:18 PM</datetime>
    /// </remarks>
    public class ETFPriceProvider : IETFPriceProvider
    {
        #region Singleton

        ETFPriceQuery query = new ETFPriceQuery();

        public static ETFPriceProvider Instance = new ETFPriceProvider();

        private ETFPriceProvider() { }

        #endregion

        #region Cache Strategy

        DateTime lastLoad = DateTime.Today;
        Dictionary<string, List<double>> cacheList = new Dictionary<string, List<double>>();

        public Dictionary<string, List<double>> CacheList
        {
            get
            {
                if ((DateTime.Now - lastLoad).TotalSeconds > 3)
                {
                    lock (this)
                    {
                        cacheList = LoadFromDB();
                        lastLoad = DateTime.Now;
                    }
                }
                return cacheList;
            }
        }

        private Dictionary<string, List<double>> LoadFromDB()
        {
            try
            {
                return query.GetPrices(2000);
            }
            catch (Exception ex)
            {
                Log.Exception("捕获到数据错误A0101", ex);
                MessageBox.Show(ex.Message);
            }
            return new Dictionary<string, List<double>>();
        }

        #endregion

        #region IETFPriceProvider Members

        /// <summary>
        /// 获取某只股票的连续历史实时价格
        /// </summary>
        /// <param name="stockCode">股票代码</param>
        /// <param name="priceCount">所需价格个数</param>
        /// <returns>
        /// 历史实时价格列表
        /// </returns>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-31 10:07 AM</datetime>
        /// </remarks>
        public List<double> GetHistoryPrice(string stockCode, int priceCount)
        {
            if (!CacheList.ContainsKey(stockCode))
                return null;

            return CacheList[stockCode].Take(priceCount).ToList();
        }

        /// <summary>
        /// 获取某只股票间隔N分钟的历史实时价格序列
        /// </summary>
        /// <param name="stockCode">股票代码</param>
        /// <param name="priceCount">所需价格个数</param>
        /// <param name="span">时间间隔</param>
        /// <returns>
        /// 历史实时价格列表
        /// </returns>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-25 5:19 PM</datetime>
        /// </remarks>
        public List<double> GetHistoryPrice(string stockCode, int priceCount, int span)
        {
            List<double> continuous = GetHistoryPrice(stockCode, priceCount * span);
            List<double> result = new List<double>();

            if (continuous == null || continuous.Count < span * priceCount - 1) //分钟实时行情数据不够
            {
                return null;
            }

            for (int i = 1; i < priceCount; i++)
            {
                result.Add(continuous[span * i - 1]);
            }

            return result;
        }

        /// <summary>
        /// 获取一只股票N分钟之前的价格.
        /// </summary>
        /// <param name="stockCode">股票代码.</param>
        /// <param name="miniuteBefore">分钟数.</param>
        /// <returns></returns>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-25 5:19 PM</datetime>
        /// </remarks>
        public double GetBeforePrice(string stockCode, int miniuteBefore)
        {
            var list = GetHistoryPrice(stockCode, miniuteBefore);

            if (list.Count < miniuteBefore)
                throw new IndexOutOfRangeException(string.Format("目前{0}没有足够的历史数据！", stockCode));

            return list[miniuteBefore - 1];
        }

        #endregion
    }
}
